package pl.vanta.utils.commons.objects;

import java.text.ParseException;

import pl.vanta.utils.commons.formats.RomanNumberFormat;
import pl.vanta.utils.commons.validators.impl.CracowClimbingScaleValidator;

public class CracowClimbingScale implements Comparable<CracowClimbingScale>
{
	private final int									romanPart;
	private final int									numberPart;
	private final SIGN									signPart;

	private static final RomanNumberFormat				format		= new RomanNumberFormat();
	private static final CracowClimbingScaleValidator	validator	= new CracowClimbingScaleValidator();

	enum SIGN
	{
		PLUS("+", 1), MINUS("-", -1), NONE("", 0);

		private String	sign;
		private int		value;

		private SIGN(String sign, int value)
		{
			this.sign = sign;
			this.value = value;
		}

		@Override
		public String toString()
		{
			return this.sign;
		}
	}

	public CracowClimbingScale(String string)
	{
		String error = validator.validateWithError(string);

		if (!"".equals(error))
		{
			throw new IllegalArgumentException(error);
		}

		int signPos = string.indexOf('+');
		if (signPos != -1)
		{
			signPart = SIGN.PLUS;
		}
		else
		{
			signPos = string.indexOf('-');

			if (signPos != -1)
			{
				signPart = SIGN.MINUS;
			}
			else
			{
				signPart = SIGN.NONE;
				signPos = string.length();
			}
		}

		int dotPos = string.indexOf('.');
		String roman;
		if (dotPos == -1)
		{
			roman = string.substring(0, signPos);
			numberPart = 0;
		}
		else
		{
			roman = string.substring(0, dotPos);
			numberPart = Integer.valueOf(string.substring(dotPos + 1, signPos));
		}

		try
		{
			romanPart = (Integer) format.parse(roman);
		}
		catch (ParseException e)
		{
			throw new IllegalArgumentException(String.format("Incorrect value: %S", string));
		}
	}

	@Override
	public String toString()
	{
		StringBuilder sb = new StringBuilder();

		sb.append(CracowClimbingScale.format.format(this.romanPart));

		if (this.numberPart != 0)
		{
			sb.append('.');
			sb.append(this.numberPart);
		}

		sb.append(this.signPart);

		return sb.toString();
	}

	@Override
	public int compareTo(CracowClimbingScale ccs)
	{
		if (ccs == null)
		{
			return 1;
		}

		if (this.romanPart != ccs.romanPart)
		{
			return Integer.valueOf(this.romanPart).compareTo(ccs.romanPart);
		}

		if (this.numberPart != ccs.numberPart)
		{
			return Integer.valueOf(this.numberPart).compareTo(ccs.numberPart);
		}

		return Integer.valueOf(this.signPart.value).compareTo(ccs.signPart.value);
	}
}